package rx.genarator.comprehension;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public abstract class TableOrView {
	
	protected DataBase dataBase;
	
	protected Set<Column> columns = new HashSet<Column>(); 
	
	protected String name ;
	protected String code ;
	protected String comment ;
	protected String id;
	protected Key primaryKey;
	protected Set<Key> keys = new HashSet<Key>();
	
	public String getId() {
		return id;
	}

	public boolean isTable(){
		return this instanceof Table;
	}
	
	public TableOrView(DataBase dataBase,String id, String name, String code, String comment) {
		super();
		if(dataBase == null || id == null || name == null || code == null)
			throw new IllegalArgumentException("dataBase:" + dataBase + ",id:" + id + ",name:" + name + ",code:" + code + ",comment:" + comment);
		this.id=id;
		this.dataBase = dataBase;
		this.name = name;
		this.code = code;
		this.comment = comment;
		ObjectsMap.put(id, this);
	}
	
	public String getCode() {
		return code;
	}
	
	public String getComment() {
		return comment;
	}
	public void setCode(String code) {
		this.code = code;
	}
	public void setComment(String comment) {
		this.comment = comment;
	}
	public void setDataBase(DataBase dataBase) {
		this.dataBase = dataBase;
	}
	public void setName(String name) {
		this.name = name;
	}
	public DataBase getDataBase() {
		return dataBase;
	}
	public String getName() {
		return name;
	}
	public synchronized void addColumn(Column column){
		this.columns.add(column);
	}
	public synchronized void addColumns(Set<Column> columns){
		this.columns.addAll(columns);
	}
	public synchronized boolean removeColumn(Column column){//FIXME
		for(Iterator<Key> iter = keys.iterator();iter.hasNext();){
			Key key = iter.next();
			if(key.columns.contains(column))iter.remove();
		}
		return this.columns.remove(column);
	}
	public synchronized void removeColumns(Set<Column> columns){
		for (Iterator iter = columns.iterator(); iter.hasNext();) {
			Column column = (Column) iter.next();
			this.removeColumn(column);
		}
	}
	
	public Set<Column> getColumns(){
		return new HashSet<Column>(this.columns);
	}
	
	public Set<Reference> getStarts(){
		Set<Reference> set = new HashSet<Reference>();
		for (Iterator iter = columns.iterator(); iter.hasNext();) {
			Column column = (Column) iter.next();
			if(column.getStart()!=null)set.add(column.getStart());
		}
		return set;
	}
	
	public Set<Reference> getEnds(){
		Set<Reference> set = new HashSet<Reference>();
		for (Iterator iter = columns.iterator(); iter.hasNext();) {
			Column column = (Column) iter.next();
			set.addAll(column.getEnds());
		}
		return set;
	}
	
	public Column createColumn(String id,String name,String code,String comment,String dataType,boolean mandatory){
		Column column = new Column(this,id,name,code,comment,dataType,mandatory);
		this.addColumn(column);
		return column;
	}

	public Key getPrimaryKey() {
		return primaryKey;
	}

	public void setPrimaryKey(Key primaryKey) {
		if(!this.keys.contains(primaryKey)) throw new NoSuchKeyContainException(primaryKey);
		this.primaryKey = primaryKey;
	}
	
	public boolean hasPk(){
		return this.primaryKey!=null;
	}
	
	public synchronized void addKey(Key key){
		if(!this.columns.containsAll(key.columns))throw new NoSuchColumnsContainException(this,key.columns);
		this.keys.add(key);
	}
	
	public synchronized boolean removeKey(Key key){
		return this.keys.remove(key);
	}

	public Set<Key> getKeys() {
		return new HashSet<Key>(keys);
	}
}
